﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using FEM.Result;

namespace PBSD_Development
{
    /// <summary>
    /// 单元
    /// </summary>
    public class ElementObj
    {
        /// <summary>
        /// 单元
        /// </summary>
        private Element element { set; get; }

        /// <summary>
        /// 框架单元
        /// </summary>
        private Frame frame
        {
            get
            {
                return (Frame)this.element;
            }
        }

        /// <summary>
        /// 分析结果
        /// </summary>
        private FEMResult result { set; get; }

        /// <summary>
        /// 塔楼序号
        /// </summary>
        public int TowerIndex
        {
            get
            {
                return this.element.Storey.TowerIndex;
            }
        }

        /// <summary>
        /// 楼层序号
        /// </summary>
        public int StoreyIndex
        {
            get
            {
                return this.element.Storey.StoreyIndex;
            }
        }

        /// <summary>
        /// ID
        /// </summary>
        public int ID
        {
            get
            {
                return this.element.ID;
            }
        }

        /// <summary>
        /// 是否框架单元
        /// </summary>
        /// <returns></returns>
        public bool isFRAME()
        {
            return (this.element is Frame);
        }

        /// <summary>
        /// 获得所有节点
        /// </summary>
        /// <returns> 节点对象列表 </returns>
        public List<NodeObj> GetNodeList(NodeSet nodeManager)
        {
            //初始化列表
            var nodeList = new List<NodeObj>();
            //遍历所有节点
            foreach(var nodeID in this.element.NodeList)
            {
                NodeObj nodeObj;
                if (nodeManager.GetNode(nodeID, out nodeObj))
                    nodeList.Add(nodeObj);
            }
            return nodeList;
        }

        /// <summary>
        /// 单元长度
        /// </summary>
        public float Length
        {
            get
            {
                return this.element.Length;
            }
        }

        #region 变形性能

        /// <summary>
        /// 变形限值
        /// </summary>
        /// <param name="loadCase"> 工况 </param>
        /// <returns> 变形限值列表 </returns>
        public List<float> GetDeformLimits(LoadCaseObj loadCase)
        {
            return this.element.GetDeformLimits(loadCase.Name);
        }

        /// <summary>
        /// 控制性能的构件变形
        /// </summary>
        /// <param name="loadCase"> 工况 </param>
        /// <returns> 构件变形 </returns>
        public float GetDeform(LoadCaseObj loadCase)
        {
            var femLC = this.result.LoadCases[loadCase.Name];
            return this.element.GetDeform(femLC);
        }

        /// <summary>
        /// 获得最大构件变形
        /// </summary>
        /// <param name="loadCase"></param>
        /// <returns></returns>
        public float GetMaxDeform(LoadCaseObj loadCase)
        {
            if (!this.isFRAME()) return this.GetDeform(loadCase);
            var femLC = this.result.LoadCases[loadCase.Name];
            var deforms = new List<float>();
            for(int i = 0; i <= 3; i++)
            {
                var deform = this.frame.GetDeform(femLC, (FRAMReusltDirect)i);
                deforms.Add(Math.Abs(deform));
            }
            return deforms.Max();
        }

        /// <summary>
        /// 控制性能的需求能力比列表
        /// </summary>
        /// <param name="loadCase"> 工况 </param>
        /// <returns> 需求能力比列表 </returns>
        public List<float> GetDeformDCRList(LoadCaseObj loadCase)
        {
            var femLC = this.result.LoadCases[loadCase.Name];
            return this.element.GetDeformDCRList(femLC);
        }

        /// <summary>
        /// 控制性能的某个性能状态下的需求能力比
        /// </summary>
        /// <param name="loadCase"> 工况 </param>
        /// <param name="deformType"> 性能类型 </param>
        /// <returns> 需求能力比 </returns>
        public float GetDeformDCR(LoadCaseObj loadCase, DeformType deformType)
        {
            var femLC = this.result.LoadCases[loadCase.Name];
            return this.element.GetDeformDCR(femLC, deformType);
        }

        /// <summary>
        /// 端部构件变形
        /// </summary>
        /// <param name="loadCase"> 工况 </param>
        /// <param name="direct"> 端部类型 </param>
        /// <returns> 构件变形 </returns>
        public float GetDeform(LoadCaseObj loadCase, FRAMReusltDirect direct)
        {
            if (!this.isFRAME()) return this.GetDeform(loadCase);
            var femLC = this.result.LoadCases[loadCase.Name];
            return this.frame.GetDeform(femLC, direct);
        }

        /// <summary>
        /// 端部变形限值
        /// </summary>
        /// <param name="loadCase"> 工况 </param>
        /// <param name="direct"> 端部类型 </param>
        /// <returns> 变形限值列表 </returns>
        public List<float> GetDeformLimits(LoadCaseObj loadCase, FRAMReusltDirect direct)
        {
            if (!this.isFRAME()) return this.GetDeformLimits(loadCase);
            var femLC = this.result.LoadCases[loadCase.Name];
            return this.frame.GetLimits(femLC, direct);
        }

        /// <summary>
        /// 端部需求能力比列表
        /// </summary>
        /// <param name="loadCase"> 工况 </param>
        /// <param name="direct"> 端部类型 </param>
        /// <returns> 需求能力比列表 </returns>
        public List<float> GetDeformDCRList(LoadCaseObj loadCase, FRAMReusltDirect direct)
        {
            if (!this.isFRAME()) return this.GetDeformDCRList(loadCase);
            var femLC = this.result.LoadCases[loadCase.Name];
            return this.frame.GetDeformDCRList(femLC, direct);
        }

        /// <summary>
        /// 端部某个性能状态下的需求能力比
        /// </summary>
        /// <param name="loadCase"> 工况 </param>
        /// <param name="direct"> 端部类型 </param>
        /// <param name="deformType"> 性能类型 </param>
        /// <returns> 需求能力比 </returns>
        public float GetDeformDCR(LoadCaseObj loadCase, FRAMReusltDirect direct, DeformType deformType)
        {
            if (!this.isFRAME()) return this.GetDeformDCR(loadCase, deformType);
            var femLC = this.result.LoadCases[loadCase.Name];
            return this.frame.GetDeformDCRatio(femLC, direct, deformType);
        }

        #endregion

        /// <summary>
        /// 最大压应变
        /// </summary>
        /// <param name="lcName"> 工况 </param>
        /// <returns> 压应变 </returns>
        public float GetCompressStrain(LoadCaseObj loadCase)
        {
            return this.element.GetStrain(loadCase.Name, SecResultType.CompressStrain);
        }

        /// <summary>
        /// 最大拉应变
        /// </summary>
        /// <param name="lcName"> 工况 </param>
        /// <returns> 拉应变 </returns>
        public float GetTensionStrain(LoadCaseObj loadCase)
        {
            return this.element.GetStrain(loadCase.Name, SecResultType.TensionStrain);
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        public ElementObj()
        {

        }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="element"></param>
        public ElementObj(Element element, FEMResult result)
        {
            this.element = element;
            this.result = result;
        }

    }
}
